package com.hrh.selectsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hrh.selectsystem.aop.MyJwtInterceptor;
import com.hrh.selectsystem.common.ErrorCode;
import com.hrh.selectsystem.constant.CommonConstant;
import com.hrh.selectsystem.exception.BusinessException;
import com.hrh.selectsystem.mapper.ChoiceRecordMapper;
import com.hrh.selectsystem.mapper.MatchResultMapper;
import com.hrh.selectsystem.mapper.RoundMapper;
import com.hrh.selectsystem.mapper.StudentMapper;
import com.hrh.selectsystem.model.dto.file.StudentExcelImport;
import com.hrh.selectsystem.model.dto.student.StudentQueryRequest;
import com.hrh.selectsystem.model.dto.student.StudentUpdateRequest;
import com.hrh.selectsystem.model.entity.*;
import com.hrh.selectsystem.model.vo.student.LoginStudentVO;
import com.hrh.selectsystem.model.vo.student.StudentByMentorVO;
import com.hrh.selectsystem.model.vo.student.StudentVO;
import com.hrh.selectsystem.service.StudentService;
import com.hrh.selectsystem.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.hrh.selectsystem.constant.UserConstant.USER_LOGIN_STATE;

/**
* @author hetongxue
* @description 针对表【student(学生)】的数据库操作Service实现
* @createDate 2024-10-23 11:33:32
*/
@Service
@Slf4j
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
    implements StudentService{
    /**
     * 盐值，混淆密码
     */
    public static final String SALT = "hrh";

    @Resource
    private StudentMapper studentMapper;
    @Resource
    private RoundMapper roundMapper;
    @Resource
    private ChoiceRecordMapper choiceRecordMapper;
    @Resource
    private MatchResultMapper matchResultMapper;

    /**
     * 学生登录
     *
     * @param studentAccount
     * @param studentPassword
     * @param request
     * @return
     */
    @Override
    public LoginStudentVO studentLogin(String studentAccount, String studentPassword, HttpServletRequest request) {
        // 1. 校验
        if (StringUtils.isAnyBlank(studentAccount, studentPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (studentPassword.length() < 6) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
        }
        // 2. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + studentPassword).getBytes());
        // 查询用户是否存在
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("studentAccount", studentAccount);
        queryWrapper.eq("studentPassword", encryptPassword);
        Student student = this.baseMapper.selectOne(queryWrapper);
        // 用户不存在
        if (student == null) {
            log.info("student login failed, studentAccount cannot match studentPassword");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
        }
        // 用户被禁用
        if (student.getStatus() == 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户已被禁用");
        }
        // 3. 记录用户的登录态
        //request.getSession().setAttribute(USER_LOGIN_STATE, student);
        return this.getLoginStudentVO(student);
    }

    /**
     * 学生注销
     * @param request
     * @return
     */
    @Override
    public boolean studentLogout(HttpServletRequest request) {
        if (request.getSession().getAttribute(USER_LOGIN_STATE) == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
        }
        // 移除登录态
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return true;
    }

    /**
     * 获取当前登录学生信息
     * @param request
     * @return
     */
    @Override
    public Student getLoginStudent(HttpServletRequest request) {
        // 从请求头中获取token
        String token = request.getHeader("token");
        // 获取用户id
        String userId = MyJwtInterceptor.getUserIdFromToken(token);
        // 查询用户
        Student student = studentMapper.selectById(userId);
        // 先判断是否已登录
/*        Object studentObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        Student currentStudent = (Student) studentObj;
        if (currentStudent == null || currentStudent.getId() == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        // 从数据库查询
        long studentId = currentStudent.getId();
        currentStudent = this.getById(studentId);*/
        if (student == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return student;
    }

    /**
     * 获取封装后学生信息(脱敏 & 登录后返回)
     * @param student
     * @return
     */
    private LoginStudentVO getLoginStudentVO(Student student) {
        if (student == null) {
            return null;
        }
        LoginStudentVO loginstudentVO = new LoginStudentVO();
        BeanUtils.copyProperties(student, loginstudentVO);
        return loginstudentVO;
    }

    /**
     * 获取封装后用户信息（脱敏）
     * @param student
     * @return
     */
    @Override
    public StudentVO getStudentVO(Student student) {
        if (student == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        StudentVO studentVO = new StudentVO();
        BeanUtils.copyProperties(student, studentVO);
        return studentVO;
    }

    /**
     * 提取更新请求的非空字段
     * @param studentUpdateRequest
     * @return
     */
    @Override
    public Student notNullStudent(StudentUpdateRequest studentUpdateRequest, Student student) {
        if (student == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (studentUpdateRequest.getStudentname() != null && !studentUpdateRequest.getStudentname().trim().isEmpty()) {
            student.setStudentname(studentUpdateRequest.getStudentname());
        }
        if (studentUpdateRequest.getStudentclass() != null && !studentUpdateRequest.getStudentclass().trim().isEmpty()) {
            student.setStudentclass(studentUpdateRequest.getStudentclass());
        }
        if (studentUpdateRequest.getStudentcollege() != null && !studentUpdateRequest.getStudentcollege().trim().isEmpty()) {
            student.setStudentcollege(studentUpdateRequest.getStudentcollege());
        }
        if (studentUpdateRequest.getGender() != null && !studentUpdateRequest.getGender().trim().isEmpty()) {
            student.setGender(studentUpdateRequest.getGender());
        }
        if (studentUpdateRequest.getStudentaccount() != null && !studentUpdateRequest.getStudentaccount().trim().isEmpty()) {
            student.setStudentaccount(studentUpdateRequest.getStudentaccount());
        }
        if (studentUpdateRequest.getStudentpassword() != null && !studentUpdateRequest.getStudentpassword().trim().isEmpty()) {
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + studentUpdateRequest.getStudentpassword()).getBytes());
            student.setStudentpassword(encryptPassword);
        }
        if (studentUpdateRequest.getUseravatar() != null && !studentUpdateRequest.getUseravatar().trim().isEmpty()) {
            student.setUseravatar(studentUpdateRequest.getUseravatar());
        }
        if (studentUpdateRequest.getUserrole() != null && !studentUpdateRequest.getUserrole().trim().isEmpty()) {
            student.setUserrole(studentUpdateRequest.getUserrole());
        }
        return student;
    }

    /**
     * 获取查询条件
     * @param studentQueryRequest
     * @return
     */
    @Override
    public Wrapper<Student> getQueryWrapper(StudentQueryRequest studentQueryRequest) {
        if (studentQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = studentQueryRequest.getId();
        String studentaccount = studentQueryRequest.getStudentaccount();
        String studentname = studentQueryRequest.getStudentname();
        String studentclass = studentQueryRequest.getStudentclass();
        String studentcollege = studentQueryRequest.getStudentcollege();
        String gender = studentQueryRequest.getGender();
        String sortField = studentQueryRequest.getSortField();
        String sortOrder = studentQueryRequest.getSortOrder();
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(id != null && id > 0, "id", id);
        queryWrapper.eq(StringUtils.isNotBlank(studentaccount), "studentaccount", studentaccount);
        queryWrapper.eq(StringUtils.isNotBlank(studentclass), "studentclass", studentclass);
        queryWrapper.eq(StringUtils.isNotBlank(studentcollege), "studentcollege", studentcollege);
        queryWrapper.eq(StringUtils.isNotBlank(gender), "gender", gender);
        queryWrapper.like(StringUtils.isNotBlank(studentname), "studentname", studentname);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 从excel批量导入学生
     * @param studentExcelList
     */
    @Override
    public void importStudentsFromExcel(List<StudentExcelImport> studentExcelList) {
        studentMapper.saveStudentBatch(studentExcelList);
    }

    /**
     * 获取导师申请学生列表
     * @param mentor
     * @return
     */
    @Override
    public List<StudentByMentorVO> listApplyStudents(Mentor mentor) {
        // 获取当前登录导师id
        Long mentorId = mentor.getId();

        Integer roundNumber = this.getStartedRound();

        // 根据不同轮次获取学生id列表
        List<Long> studentIdList = null;

        if (roundNumber == 1){
            QueryWrapper<ChoiceRecord> choiceRecordQueryWrapper = new QueryWrapper<>();
            choiceRecordQueryWrapper.eq("firstchoice", mentorId);
            choiceRecordQueryWrapper.eq("firststatus", "pending");
            List<ChoiceRecord> choiceRecordList = choiceRecordMapper.selectList(choiceRecordQueryWrapper);

            studentIdList = choiceRecordList.stream()
                    .map(ChoiceRecord::getStudentid)
                    .collect(Collectors.toList());
        }

        if (roundNumber == 2){
            QueryWrapper<ChoiceRecord> choiceRecordQueryWrapper = new QueryWrapper<>();
            choiceRecordQueryWrapper.eq("secondchoice", mentorId);
            choiceRecordQueryWrapper.eq("secondstatus", "pending");
            List<ChoiceRecord> choiceRecordList = choiceRecordMapper.selectList(choiceRecordQueryWrapper);

            studentIdList = choiceRecordList.stream()
                    .map(ChoiceRecord::getStudentid)
                    .collect(Collectors.toList());
        }

        if (roundNumber == 3){
            QueryWrapper<ChoiceRecord> choiceRecordQueryWrapper = new QueryWrapper<>();
            choiceRecordQueryWrapper.eq("thirdchoice", mentorId);
            choiceRecordQueryWrapper.eq("thirdstatus", "pending");
            List<ChoiceRecord> choiceRecordList = choiceRecordMapper.selectList(choiceRecordQueryWrapper);

            studentIdList = choiceRecordList.stream()
                    .map(ChoiceRecord::getStudentid)
                    .collect(Collectors.toList());
        }
        // 判断学生id列表是否为空
       if (studentIdList == null || studentIdList.isEmpty()){
            // 返回一个空的List<StudentByMentorVO>
            List<StudentByMentorVO> studentByMentorVOList = new ArrayList<>();
            return studentByMentorVOList;
        }
        // 获取学生信息
        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.in("id", studentIdList);
        List<Student> studentList = studentMapper.selectList(studentQueryWrapper);
        // Student转换为StudentByMentorVO
        List<StudentByMentorVO> studentByMentorVOList = studentList.stream()
                .map(student -> {
                    StudentByMentorVO studentByMentorVO = new StudentByMentorVO();
                    BeanUtils.copyProperties(student, studentByMentorVO);
                    return studentByMentorVO;
                })
                .collect(Collectors.toList());

        return studentByMentorVOList;
    }

    /**
     * 获取当前进行中的轮次
     * @return
     */
    public Integer getStartedRound() {
        QueryWrapper<Round> queryWrapper = new QueryWrapper<>();
        String status = "started";
        queryWrapper.eq(StringUtils.isNotBlank(status), "status", status);
        Round round = roundMapper.selectOne(queryWrapper);

        if (round == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "当前无进行中轮次");
        }

        Integer roundNumber = round.getRoundnumber();
        if (roundNumber != 1 && roundNumber != 2 && roundNumber != 3) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "无效的轮次编号");
        }

        return roundNumber;
    }

    /**
     * 获取导师已选学生列表
     * @param mentor
     * @return
     */
    @Override
    public List<StudentByMentorVO> listSuccessStudents(Mentor mentor) {
        // 获取当前登录导师id
        Long mentorId = mentor.getId();
        // 获取已选学生id列表
        QueryWrapper<MatchResult> matchRecordQueryWrapper = new QueryWrapper<>();
        matchRecordQueryWrapper.eq("mentorid", mentorId);
        List<MatchResult> matchRecordList = matchResultMapper.selectList(matchRecordQueryWrapper);
        List<Long> studentIdList = matchRecordList.stream()
                .map(MatchResult::getStudentid)
                .collect(Collectors.toList());
        // 判断学生id列表是否为空
        if (studentIdList.isEmpty()){
            // 返回一个空的List<StudentByMentorVO>
            List<StudentByMentorVO> studentByMentorVOList = new ArrayList<>();
            return studentByMentorVOList;
        }
        return studentMapper.selectList(new QueryWrapper<Student>().in("id", studentIdList))
                .stream()
                .map(student -> {
                    StudentByMentorVO studentByMentorVO = new StudentByMentorVO();
                    BeanUtils.copyProperties(student, studentByMentorVO);
                    return studentByMentorVO;
                })
                .collect(Collectors.toList());
    }

    /**
     * 获取未分配导师的学生
     * @param studentQueryRequest
     * @return
     */
    @Override
    public Page<Student> getStudentNoMentor(StudentQueryRequest studentQueryRequest, Long current, Long size) {
        //region
//        // 创建分页对象
//        Page<Student> page = new Page<>(current, size);
//        // 获取所有学生列表
//        List<Student> studentList = studentMapper.selectPage(page, getQueryWrapper(studentQueryRequest)).getRecords();
//
////        List<Student> studentList = studentMapper.selectList(getQueryWrapper(studentQueryRequest));
//
//        List<Long> studentIdList = studentList.stream().map(Student::getId).collect(Collectors.toList());
//
//        QueryWrapper<MatchResult> matchRecordQueryWrapper = new QueryWrapper<>();
//        matchRecordQueryWrapper.in("studentid", studentIdList);
//        List<MatchResult> matchRecordList = matchResultMapper.selectList(matchRecordQueryWrapper);
//        List<Long> matchStudentIdList = matchRecordList.stream().map(MatchResult::getStudentid).collect(Collectors.toList());
//        studentIdList.removeAll(matchStudentIdList);
//
//        return studentMapper.selectList(new QueryWrapper<Student>().in("id", studentIdList));
        //endregion
        //region
        // 创建分页对象
//        Page<Student> page = new Page<>(current, size);
//
//        // 获取所有符合条件的学生总数
//        long total = studentMapper.selectCount(getQueryWrapper(studentQueryRequest));
//        page.setTotal(total);
//        // 获取所有符合条件的学生列表
//        List<Student> allStudents = studentMapper.selectPage(page, getQueryWrapper(studentQueryRequest)).getRecords();
//
//        // 获取已分配导师的学生ID列表
//        List<Long> matchedStudentIds = matchResultMapper.selectList(
//                        new QueryWrapper<MatchResult>()
//                                .select("studentid")
//                                .in("studentid", allStudents.stream().map(Student::getId).collect(Collectors.toList()))
//                ).stream()
//                .map(MatchResult::getStudentid)
//                .collect(Collectors.toList());
//
//        // 过滤出未分配导师的学生
//        List<Student> noMentorStudents = allStudents.stream()
//                .filter(student -> !matchedStudentIds.contains(student.getId()))
//                .collect(Collectors.toList());
//
//        // 设置分页结果
//        page.setRecords(noMentorStudents);
//        return page;
        //endregion
        Page<Student> page = new Page<>(current, size);

        //获取学生总数（student表内所有学生）
        long allStudentCount = studentMapper.selectCount(null);
        // 获取所有符合条件的学生总数
        long total = studentMapper.selectCount(getQueryWrapper(studentQueryRequest));
        page.setTotal(total);

        // 初始化学生列表
        List<Student> noMentorStudents = new ArrayList<>();
        long currentPage = current;

        while (noMentorStudents.size() < size && currentPage <= allStudentCount / size + 1) {
            Page<Student> currentPageObj = new Page<>(currentPage, size - noMentorStudents.size());
            List<Student> allStudents = studentMapper.selectPage(currentPageObj, getQueryWrapper(studentQueryRequest)).getRecords();

            // 获取已分配导师的学生ID列表
            List<Long> matchedStudentIds = matchResultMapper.selectList(
                            new QueryWrapper<MatchResult>()
                                    .select("studentid")
                                    .in("studentid", allStudents.stream().map(Student::getId).collect(Collectors.toList()))
                    ).stream()
                    .map(MatchResult::getStudentid)
                    .collect(Collectors.toList());

            // 过滤出未分配导师的学生并添加到结果中
            List<Student> additionalNoMentorStudents = allStudents.stream()
                    .filter(student -> !matchedStudentIds.contains(student.getId()))
                    .collect(Collectors.toList());

            noMentorStudents.addAll(additionalNoMentorStudents);

            // 如果当前页没有更多学生，则退出循环
            if (allStudents.size() < currentPageObj.getSize()) {
                break;
            }

            currentPage++;
        }

// 设置分页结果
        page.setRecords(noMentorStudents.subList(0, (int) Math.min(noMentorStudents.size(), size)));
        return page;

    }

}




